package com.spukmk3me.math;

public final class FPMath
{
    private FPMath() {}
    
    /**
     *  Multiply two fixed-point number.
     *  @param fnumber1 The first number.
     *  @param fnumber2 The seconds number.
     *  @return The product.
     */
    public static int fpMul( int fnumber1, int fnumber2 )
    {
        return (int)(((long)fnumber1 * (long)fnumber2) >> 16);
    }

    /**
     *  Divide two fixed-point number.
     *  @param fnumber1 The dividend.
     *  @param fnumber2 The divisor.
     *  @return The quotient.
     */
    public static int fpDiv( int fnumber1, int fnumber2 )
    {
        return (int)(((long)fnumber1 << 32) / (long)fnumber2 >> 16);
    }

    /**
     *  Round a fixed-point real number.
     *  @param fnumber Number to be rounded.
     *  @return Rounded result.
     */
    public static short fpRound( int fnumber )
    {
        if ( (fnumber & 0x00008000) != 0 )
            return (short)((fnumber >> 16) + 1);

        return (short)(fnumber >> 16);
    }

    /**
     *  Calculate the sine of angle x. Unimplemented
     *  @param x Measured in radiant, it's a fixed-point number.
     *  @return sin(x).
     */
    public static int fpSin( int x )
    {
        int sinx = 0, epsilon, factorial, k;
        int squaredX = fpMul( x, x );
        boolean sign = true;

        epsilon = factorial = k = 1;

        while ( epsilon != 0 )
        {
            epsilon = x / factorial;

            if ( sign )
                sinx += epsilon;
            else
                sinx -= epsilon;

            factorial *= ++k;
            factorial *= ++k;
            x = fpMul( x, squaredX );
        }

        return sinx;
    }

    /**
     *  Calculate the cosine of angle. Unimplemented
     *  @param angle Measured in radius, it's a fixed-point number.
     *  @return Cosine of angle.
     */
    public static int fpCos( int angle )
    {
        return 0;
    }

    /**
     *  Calculate the tangent of angle. Unimplemented
     *  @param angle Measured in radius, it's a fixed-point number.
     *  @return Tangent of angle.
     */
    public static int fpTan( int angle )
    {
        return 0;
    }

    /**
     *  Calculate the arcsine of angle. Unimplemented
     *  @param angle Measured in radius, it's a fixed-point number.
     *  @return Arcsine of angle.
     */
    public static int fpArcsin( int angle )
    {
        return 0;
    }

    /**
     *  Calculate the arccosine of angle. Unimplemented
     *  @param angle Measured in radius, it's a fixed-point number.
     *  @return Arccosine of angle.
     */
    public static int fpArccos( int angle )
    {
        return 0;
    }

    /**
     *  Calculate the arctan of angle. Unimplemented
     *  @param angle Measured in radius, it's a fixed-point number.
     *  @return Arctan of angle.
     */
    public static int fpArctan( int angle )
    {
        return 0;
    }

    /**
     *  Calculate the natural logarithm of x. Unimplemented.
     *  @param x A fixed-point number.
     *  @return Natural logarithm of x.
     */
    public static int fpLog( int x )
    {
        return 0;
    }

    /**
     *  Calculate n power of x. Unimplemented
     *  @param x Base number.
     *  @param n The power.
     *  @return n power of x.
     */
    public static int fpPow( int x, int n )
    {
        return 0;
    }
}
